"""
订单模型
包含订单和订单项的类定义
"""

from enum import Enum
from datetime import datetime
from typing import List, Dict, Any
from core.utils.logger import debug, info, warning, error


class OrderStatus(Enum):
    """订单状态枚举"""
    PENDING = "pending"  # 待支付
    PAID = "paid"  # 已支付
    SHIPPED = "shipped"  # 已发货
    COMPLETED = "completed"  # 已完成
    CANCELLED = "cancelled"  # 已取消
    
    def __str__(self):
        return self.value
    
    @classmethod
    def from_string(cls, status_str: str):
        """从字符串创建状态枚举"""
        try:
            return cls(status_str.lower())
        except ValueError:
            return cls.PENDING


class OrderItem:
    """订单项 - 表示订单中的单个商品"""
    
    def __init__(self, product_id: str, product_name: str, price: float, 
                 quantity: int, subtotal: float = None):
        self.product_id = product_id
        self.product_name = product_name
        self.price = price
        self.quantity = quantity
        self.subtotal = subtotal if subtotal is not None else price * quantity
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'product_id': self.product_id,
            'name': self.product_name,
            'price': self.price,
            'quantity': self.quantity,
            'subtotal': self.subtotal
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]):
        """从字典创建订单项"""
        return cls(
            product_id=data.get('product_id', ''),
            product_name=data.get('name', ''),
            price=data.get('price', 0.0),
            quantity=data.get('quantity', 1),
            subtotal=data.get('subtotal')
        )
    
    def __repr__(self):
        return f"OrderItem({self.product_name} x{self.quantity} = ¥{self.subtotal:.2f})"


class Order:
    """订单类 - 表示一个完整的订单"""
    
    def __init__(self, order_id: str, user_id: str, items: List[OrderItem],
                 total: float, status: OrderStatus = OrderStatus.PENDING,
                 created_at: str = None, updated_at: str = None,
                 shipping_address: str = None):
        self.order_id = order_id
        self.user_id = user_id
        self.items = items
        self.total = total
        self.status = status if isinstance(status, OrderStatus) else OrderStatus.from_string(status)
        self.created_at = created_at or datetime.now().isoformat()
        self.updated_at = updated_at or self.created_at
        self.shipping_address = shipping_address or ""
    
    @property
    def item_count(self) -> int:
        """订单中的商品总数"""
        return sum(item.quantity for item in self.items)
    
    def calculate_total(self) -> float:
        """重新计算订单总金额"""
        self.total = sum(item.subtotal for item in self.items)
        return self.total
    
    def update_status(self, new_status: OrderStatus):
        """更新订单状态"""
        old_status = self.status
        self.status = new_status
        self.updated_at = datetime.now().isoformat()
        info(f"订单 {self.order_id} 状态更新: {old_status} -> {new_status}")
    
    def can_cancel(self) -> bool:
        """判断订单是否可以取消"""
        return self.status in [OrderStatus.PENDING, OrderStatus.PAID]
    
    def can_pay(self) -> bool:
        """判断订单是否可以支付"""
        return self.status == OrderStatus.PENDING
    
    def can_ship(self) -> bool:
        """判断订单是否可以发货"""
        return self.status == OrderStatus.PAID
    
    def can_complete(self) -> bool:
        """判断订单是否可以完成"""
        return self.status == OrderStatus.SHIPPED
    
    def can_delete(self) -> bool:
        """判断订单是否可以删除"""
        # 允许删除已取消、已完成、已发货的订单
        # 不允许删除待支付和已支付的订单（需要先取消或完成）
        return self.status in [OrderStatus.CANCELLED, OrderStatus.COMPLETED, OrderStatus.SHIPPED]
    
    def can_transition_to(self, new_status: 'OrderStatus') -> bool:
        """判断是否可以转换到指定状态"""
        current = self.status
        
        # 定义允许的状态转换
        allowed_transitions = {
            OrderStatus.PENDING: [OrderStatus.PAID, OrderStatus.CANCELLED],
            OrderStatus.PAID: [OrderStatus.SHIPPED, OrderStatus.CANCELLED],
            OrderStatus.SHIPPED: [OrderStatus.COMPLETED],
            OrderStatus.COMPLETED: [],  # 已完成状态不能转换
            OrderStatus.CANCELLED: []   # 已取消状态不能转换
        }
        
        return new_status in allowed_transitions.get(current, [])
    
    def cancel(self):
        """取消订单"""
        if self.can_cancel():
            self.update_status(OrderStatus.CANCELLED)
            return True
        else:
            warning(f"Order {self.order_id} in status {self.status} cannot be cancelled")
            return False
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'order_id': self.order_id,
            'user_id': self.user_id,
            'items': [item.to_dict() for item in self.items],
            'total': self.total,
            'status': self.status.value,
            'created_at': self.created_at,
            'updated_at': self.updated_at,
            'shipping_address': self.shipping_address
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]):
        """从字典创建订单"""
        items = [OrderItem.from_dict(item_data) for item_data in data.get('items', [])]
        
        return cls(
            order_id=data.get('order_id', ''),
            user_id=data.get('user_id', ''),
            items=items,
            total=data.get('total', 0.0),
            status=data.get('status', 'pending'),
            created_at=data.get('created_at'),
            updated_at=data.get('updated_at'),
            shipping_address=data.get('shipping_address', '')
        )
    
    def get_status_display(self) -> str:
        """获取状态的显示文本"""
        status_display = {
            OrderStatus.PENDING: "Pending",
            OrderStatus.PAID: "Paid",
            OrderStatus.SHIPPED: "Shipped",
            OrderStatus.COMPLETED: "Completed",
            OrderStatus.CANCELLED: "Cancelled"
        }
        return status_display.get(self.status, str(self.status))
    
    def get_status_color(self) -> str:
        """获取状态对应的颜色"""
        status_colors = {
            OrderStatus.PENDING: "#E67E22",  # 橙色
            OrderStatus.PAID: "#3498DB",  # 蓝色
            OrderStatus.SHIPPED: "#9B59B6",  # 紫色
            OrderStatus.COMPLETED: "#27AE60",  # 绿色
            OrderStatus.CANCELLED: "#95A5A6"  # 灰色
        }
        return status_colors.get(self.status, "#000000")
    
    def __repr__(self):
        return f"Order({self.order_id}, {self.item_count} items, ¥{self.total:.2f}, {self.status})"

